package com.tpp.base.service.impl;

import com.alibaba.nacos.api.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tpp.base.feign.AdminSchedulerFeign;
import com.tpp.base.mapper.CinemaMapper;
import com.tpp.base.mapper.ItemMapper;
import com.tpp.base.service.AdminItemService;
import com.tpp.base.vo.ItemSearchVo;
import com.tpp.comm.client.AdminSchedulerClient;
import com.tpp.comm.pojo.TpCinema;
import com.tpp.comm.pojo.TpItem;
import com.tpp.comm.vo.ItemSchedulerVo;
import com.tpp.comm.vo.PageData;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class AdminItemServiceImpl implements AdminItemService {

    @Resource
    private ItemMapper itemMapper;

    @Resource
    private AdminSchedulerFeign adminSchedulerFeign;

    @Resource
    private CinemaMapper cinemaMapper;

    @Override
    public PageData findItems(ItemSearchVo itemSearchVo) {
        QueryWrapper<TpItem> tpItemQueryWrapper = new QueryWrapper<>();
        if(itemSearchVo.getId()!=null&&itemSearchVo.getId()!=0)
            tpItemQueryWrapper.lambda().eq(TpItem::getId,itemSearchVo.getId());
        if(!StringUtils.isEmpty(itemSearchVo.getItemName()))
            tpItemQueryWrapper.lambda().like(TpItem::getItemName,itemSearchVo.getItemName());
        if(itemSearchVo.getStartTime()!=null)
            tpItemQueryWrapper.lambda().ge(TpItem::getStartTime,itemSearchVo.getStartTime());
        if(itemSearchVo.getEndTime()!=null)
            tpItemQueryWrapper.lambda().le(TpItem::getStartTime,itemSearchVo.getEndTime());
        Page<TpItem> tpItemPage = itemMapper.selectPage(Page.of(itemSearchVo.getCurrentPage(), itemSearchVo.getPageSize()), tpItemQueryWrapper);
        return PageData.builder()
                .currentPage(tpItemPage.getCurrent())
                .total(tpItemPage.getTotal())
                .pageSize(tpItemPage.getSize())
                .pageCount(tpItemPage.getPages())
                .rows(tpItemPage.getRecords())
                .build();
    }

    @Override
    public void addItem(TpItem tpItem) {
        itemMapper.insert(tpItem);
    }

    @Override
    public void updateItem(TpItem tpItem) {
        itemMapper.updateById(tpItem);
    }

    @Override
    public void deleteItem(Integer id) {
        itemMapper.deleteById(id);
    }

    @Override
    public TpItem findById(Integer id) {
        return itemMapper.selectById(id);
    }

    @Override
    public Map<LocalDate, List<TpItem>> findItemGroupByStartTime(ItemSearchVo itemSearchVo) {
        //构建查询条件
        QueryWrapper<TpItem> tpItemQueryWrapper = new QueryWrapper<>();
        tpItemQueryWrapper.between("start_time",itemSearchVo.getStartTime(),itemSearchVo.getStartTime().plusDays(1));
        List<TpItem> items = itemMapper.selectList(tpItemQueryWrapper);
        Map<LocalDate, List<TpItem>> collect = items.stream().collect(Collectors.groupingBy(new Function<TpItem, LocalDate>() {
            @Override
            public LocalDate apply(TpItem tpItem) {
                LocalDateTime startTime = tpItem.getStartTime();
                LocalDate localDate = startTime.toLocalDate();
                return localDate;
            }
        }));
        return collect;
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void addItemScheduler(ItemSchedulerVo itemSchedulerVo) {
        //添加item
        ItemSchedulerVo.SeatPrice[] seatPrices = itemSchedulerVo.getSeatPrices();
        Arrays.sort(seatPrices, (o1,o2)->{
            if(o1.getPrice()>o2.getPrice()) return 1;
            if(o1.getPrice()<o2.getPrice()) return -1;
            return 0;
        });

        TpCinema tpCinema = cinemaMapper.selectById(itemSchedulerVo.getCinemaId());

        itemMapper.update(TpItem.builder().build(),new UpdateWrapper<TpItem>()
                .lambda()
                .set(TpItem::getStartTime,itemSchedulerVo.getStartTime())
                .set(TpItem::getEndTime,itemSchedulerVo.getEndTime())
                .set(TpItem::getMaxPrice,seatPrices[seatPrices.length-1].getPrice())
                .set(TpItem::getLongitude,tpCinema.getLongitude())
                .set(TpItem::getLatitude,tpCinema.getLatitude())
                .set(TpItem::getMinPrice,seatPrices[0].getPrice())
                .eq(TpItem::getId,itemSchedulerVo.getItemId()));

        //远程调用scheduler服务添加排期
        adminSchedulerFeign.addScheduler(itemSchedulerVo);
    }
}
